import React, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
import './DraggableIcon.css';
import { NotificationData } from '../types/api';
import webSocketService from '../services/websocketService';

interface DraggableIconProps {
  onIconClick?: () => void;
}

interface NotificationWindowProps {
  notification: NotificationData;
  visible: boolean;
  position: { x: number; y: number };
  iconPosition: { x: number; y: number };
  onClose: () => void;
}

const NotificationWindow: React.FC<NotificationWindowProps> = ({ notification, visible, position, iconPosition, onClose }) => {
  const [animationState, setAnimationState] = useState<'hidden' | 'appearing' | 'visible' | 'disappearing'>('hidden');
  const windowRef = useRef<HTMLDivElement>(null);
  const [isMounted, setIsMounted] = useState(false);
  
  // 计算图标中心点位置（图标是60x60，所以中心点需要偏移30px）
  const iconCenterX = iconPosition.x + 30;
  const iconCenterY = iconPosition.y + 30;
  
  // 计算窗口中心点位置（窗口是280x120，所以中心点需要偏移140px和60px）
  const windowCenterX = position.x + 140;
  const windowCenterY = position.y + 60;
  
  // 计算从窗口中心到图标中心的偏移量
  const offsetX = iconCenterX - windowCenterX;
  const offsetY = iconCenterY - windowCenterY;

  // 控制动画状态
  useEffect(() => {
    if (visible && !isMounted) {
      setIsMounted(true);
      setAnimationState('appearing');
    } else if (!visible && isMounted) {
      setAnimationState('disappearing');
    }
  }, [visible, isMounted]);

  // 处理动画效果
  useEffect(() => {
    if (isMounted && animationState === 'appearing' && windowRef.current) {
      const element = windowRef.current;
      
      // 设置初始状态：从图标中心开始
      element.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(0)`;
      element.style.opacity = '0';
      element.style.transition = 'none';
      
      // 强制重绘
      void element.offsetHeight;
      
      // 开始出现动画
      element.style.transition = 'all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)';
      element.style.transform = 'translate(0px, 0px) scale(1)';
      element.style.opacity = '1';
      
      // 动画完成后设置为可见状态
      setTimeout(() => {
        setAnimationState('visible');
      }, 500);
    } else if (isMounted && animationState === 'disappearing' && windowRef.current) {
      const element = windowRef.current;
      
      // 开始消失动画
      element.style.transition = 'all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94)';
      element.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(0)`;
      element.style.opacity = '0';
      
      // 动画完成后隐藏
      setTimeout(() => {
        setAnimationState('hidden');
        setIsMounted(false);
      }, 400);
    }
  }, [animationState, isMounted, offsetX, offsetY]);


  // 如果组件未挂载，不渲染
  if (!isMounted) {
    return null;
  }

  return (
    <div
      ref={windowRef}
      className="notification-window"
      style={{
        position: 'fixed',
        left: `${position.x}px`,
        top: `${position.y}px`,
        zIndex: 1000,
        transformOrigin: 'center center',
        // 初始状态由JavaScript控制
      }}
    >
      <div className="notification-card-native">
        <div className="notification-header">
          <h4 className="notification-title">{notification.title}</h4>
        </div>
        
        <div className="notification-content">
          <p className="notification-summary">{notification.summary}</p>
        </div>
      </div>
    </div>
  );
};

// 拖动消息窗口组件
interface DragMessageWindowProps {
  visible: boolean;
  position: { x: number; y: number };
  iconPosition: { x: number; y: number };
  onClose: () => void;
}

const DragMessageWindow: React.FC<DragMessageWindowProps> = ({ visible, position, iconPosition, onClose }) => {
  const [animationState, setAnimationState] = useState<'hidden' | 'appearing' | 'visible' | 'disappearing'>('hidden');
  const windowRef = useRef<HTMLDivElement>(null);
  const [isMounted, setIsMounted] = useState(false);
  
  // 计算图标中心点位置（图标是60x60，所以中心点需要偏移30px）
  const iconCenterX = iconPosition.x + 30;
  const iconCenterY = iconPosition.y + 30;
  
  // 计算窗口中心点位置（窗口是280x80，所以中心点需要偏移140px和40px）
  const windowCenterX = position.x + 140;
  const windowCenterY = position.y + 40;
  
  // 计算从窗口中心到图标中心的偏移量
  const offsetX = iconCenterX - windowCenterX;
  const offsetY = iconCenterY - windowCenterY;

  // 控制动画状态
  useEffect(() => {
    if (visible && !isMounted) {
      setIsMounted(true);
      setAnimationState('appearing');
    } else if (!visible && isMounted) {
      setAnimationState('disappearing');
    }
  }, [visible, isMounted]);

  // 处理动画效果
  useEffect(() => {
    if (isMounted && animationState === 'appearing' && windowRef.current) {
      const element = windowRef.current;
      
      // 设置初始状态：从图标中心开始
      element.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(0)`;
      element.style.opacity = '0';
      element.style.transition = 'none';
      
      // 强制重绘
      void element.offsetHeight;
      
      // 开始出现动画
      element.style.transition = 'all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)';
      element.style.transform = 'translate(0px, 0px) scale(1)';
      element.style.opacity = '1';
      
      // 动画完成后设置为可见状态
      setTimeout(() => {
        setAnimationState('visible');
      }, 500);
    } else if (isMounted && animationState === 'disappearing' && windowRef.current) {
      const element = windowRef.current;
      
      // 开始消失动画
      element.style.transition = 'all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94)';
      element.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(0)`;
      element.style.opacity = '0';
      
      // 动画完成后隐藏
      setTimeout(() => {
        setAnimationState('hidden');
        setIsMounted(false);
      }, 400);
    }
  }, [animationState, isMounted, offsetX, offsetY]);

  // 如果组件未挂载，不渲染
  if (!isMounted) {
    return null;
  }

  return (
    <div
      ref={windowRef}
      className="notification-window"
      style={{
        position: 'fixed',
        left: `${position.x}px`,
        top: `${position.y}px`,
        zIndex: 1000,
        transformOrigin: 'center center',
        // 初始状态由JavaScript控制
      }}
    >
      <div className="notification-card-native">
        <div className="notification-header">
          <h1 className="notification-title">吊毛，你要干嘛！</h1>
        </div>
        
      </div>
    </div>
  );
};

const DraggableIcon: React.FC<DraggableIconProps> = ({ onIconClick }) => {
  const [position, setPosition] = useState({ x: 50, y: 50 });
  const [isDragging, setIsDragging] = useState(false);
  const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
  const [isEnabled, setIsEnabled] = useState(false);
  const [currentNotification, setCurrentNotification] = useState<NotificationData | null>(null);
  const [showNotification, setShowNotification] = useState(false);
  const [isShowingNotification, setIsShowingNotification] = useState(false);
  const [showDragMessage, setShowDragMessage] = useState(false);
  const [isShowingDragMessage, setIsShowingDragMessage] = useState(false);
  const [dragTimer, setDragTimer] = useState<NodeJS.Timeout | null>(null);
  const iconRef = useRef<HTMLDivElement>(null);

  // 约束位置在窗口内
  const constrainPosition = useCallback((x: number, y: number) => {
    const iconSize = 60;
    const maxX = window.innerWidth - iconSize;
    const maxY = window.innerHeight - iconSize;
    
    return {
      x: Math.max(0, Math.min(x, maxX)),
      y: Math.max(0, Math.min(y, maxY))
    };
  }, []);

  // 计算通知窗口位置
  const notificationPosition = useMemo(() => {
    // 使用变大后的图标尺寸来计算位置
    const iconSize = isShowingNotification ? 70 : 60;
    const iconScale = isShowingNotification ? 1.15 : 1;
    const actualIconSize = iconSize * iconScale;
    
    const windowWidth = 280;
    const windowHeight = 80; // 减少高度，因为移除了标签和时间
    const margin = 10;
    
    let windowX = position.x + actualIconSize + 10; // 默认在图标右侧
    let windowY = position.y - 10; // 稍微向上偏移
    
    // 如果右侧空间不够，放在左侧
    if (windowX + windowWidth > window.innerWidth - margin) {
      windowX = position.x - windowWidth - 10;
    }
    
    // 如果左侧也不够，尝试放在图标上方
    if (windowX < margin) {
      windowX = position.x - windowWidth / 2 + actualIconSize / 2; // 居中
      windowY = position.y - windowHeight - 10;
    }
    
    // 如果上方也不够，放在图标下方
    if (windowY < margin) {
      windowY = position.y + actualIconSize + 10;
    }
    
    // 最终确保窗口在页面内
    windowX = Math.max(margin, Math.min(windowX, window.innerWidth - windowWidth - margin));
    windowY = Math.max(margin, Math.min(windowY, window.innerHeight - windowHeight - margin));
    
    return { x: windowX, y: windowY };
  }, [position.x, position.y, isShowingNotification]);

  // 计算拖动消息窗口位置
  const dragMessagePosition = useMemo(() => {
    // 使用变大后的图标尺寸来计算位置（与通知窗口保持一致）
    const iconSize = 70; // 变大后的图标尺寸
    const iconScale = 1.15; // 放大倍数
    const actualIconSize = iconSize * iconScale;
    
    const windowWidth = 280;
    const windowHeight = 80;
    const margin = 10;
    
    let windowX = position.x + actualIconSize + 10; // 默认在变大后的图标右侧
    let windowY = position.y - 10; // 稍微向上偏移
    
    // 如果右侧空间不够，放在左侧
    if (windowX + windowWidth > window.innerWidth - margin) {
      windowX = position.x - windowWidth - 10;
    }
    
    // 如果左侧也不够，尝试放在图标上方
    if (windowX < margin) {
      windowX = position.x - windowWidth / 2 + actualIconSize / 2; // 居中
      windowY = position.y - windowHeight - 10;
    }
    
    // 如果上方也不够，放在图标下方
    if (windowY < margin) {
      windowY = position.y + actualIconSize + 10;
    }
    
    // 最终确保窗口在页面内
    windowX = Math.max(margin, Math.min(windowX, window.innerWidth - windowWidth - margin));
    windowY = Math.max(margin, Math.min(windowY, window.innerHeight - windowHeight - margin));
    
    return { x: windowX, y: windowY };
  }, [position]);

  // 初始化WebSocket连接
  const initializeWebSocket = useCallback(async () => {
    if (!isEnabled) return;
    
    try {
      const token = localStorage.getItem('token');
      console.log('检查token:', token ? '存在' : '不存在');
      
      if (!token) {
        console.log('未找到认证token，无法连接WebSocket');
        return;
      }

      console.log('开始连接WebSocket...');
      await webSocketService.connect(token);
      console.log('WebSocket连接已建立');
    } catch (error) {
      console.error('WebSocket连接失败:', error);
    }
  }, [isEnabled]);

  // 隐藏通知
  const hideNotificationWindow = useCallback(() => {
    setShowNotification(false);
    // 同时开始图标变小动画
    setIsShowingNotification(false);
    
    // 等待消失动画完成后再清理状态
    setTimeout(() => {
      setCurrentNotification(null);
    }, 500);
  }, []);

  // 显示通知
  const showNotificationWindow = useCallback((notification: NotificationData) => {
    setCurrentNotification(notification);
    // 先设置图标状态，然后显示窗口
    setIsShowingNotification(true);
    
    // 稍微延迟显示窗口，让图标变大动画先开始
    setTimeout(() => {
      setShowNotification(true);
    }, 100);
    
    // 4秒后自动隐藏
    setTimeout(() => {
      hideNotificationWindow();
    }, 4000);
  }, [hideNotificationWindow]);

  // 监听通知事件
  useEffect(() => {
    const handleNewNotification = (event: CustomEvent) => {
      const notification = event.detail;
      if (notification && isEnabled) {
        showNotificationWindow(notification);
      }
    };

    const handleHideNotification = () => {
      if (showNotification) {
        hideNotificationWindow();
      }
    };

    window.addEventListener('new-notification', handleNewNotification as EventListener);
    window.addEventListener('hide-notification', handleHideNotification);
    
    return () => {
      window.removeEventListener('new-notification', handleNewNotification as EventListener);
      window.removeEventListener('hide-notification', handleHideNotification);
    };
  }, [isEnabled, showNotification, showNotificationWindow, hideNotificationWindow]);

  // 检查虚拟人物是否启用
  useEffect(() => {
    const checkEnabled = () => {
      const enabled = localStorage.getItem('virtual-character-enabled') === 'true';
      setIsEnabled(enabled);
    };

    checkEnabled();
    
    const handleStorageChange = () => {
      checkEnabled();
    };
    const handleVirtualCharacterChange = () => {
      checkEnabled();
    };
    
    window.addEventListener('storage', handleStorageChange);
    window.addEventListener('virtual-character-changed', handleVirtualCharacterChange);
    
    return () => {
      window.removeEventListener('storage', handleStorageChange);
      window.removeEventListener('virtual-character-changed', handleVirtualCharacterChange);
    };
  }, []);

  // WebSocket连接管理
  useEffect(() => {
    if (isEnabled) {
      initializeWebSocket();
    } else {
      // 断开WebSocket连接
      webSocketService.disconnect();
    }

    return () => {
      // 组件卸载时断开连接
      webSocketService.disconnect();
    };
  }, [isEnabled, initializeWebSocket]);

  // 组件卸载时清理计时器
  useEffect(() => {
    return () => {
      if (dragTimer) {
        clearTimeout(dragTimer);
      }
    };
  }, [dragTimer]);

  // 鼠标事件处理
  const handleMouseDown = (e: React.MouseEvent) => {
    if (e.button !== 0) return; // 只处理左键
    
    setIsDragging(true);
    setDragStart({
      x: e.clientX - position.x,
      y: e.clientY - position.y
    });
    
    // 开始拖动计时器，5秒后显示消息
    const timer = setTimeout(() => {
      // 先设置图标状态，然后显示窗口
      setIsShowingDragMessage(true);
      
      // 稍微延迟显示窗口，让图标变大动画先开始
      setTimeout(() => {
        setShowDragMessage(true);
      }, 100);
    }, 5000);
    setDragTimer(timer);
    
    e.preventDefault();
  };

  const handleMouseMove = useCallback((e: MouseEvent) => {
    if (!isDragging) return;
    
    const newPosition = constrainPosition(
      e.clientX - dragStart.x,
      e.clientY - dragStart.y
    );
    setPosition(newPosition);
  }, [isDragging, dragStart, constrainPosition]);

  const handleMouseUp = useCallback(() => {
    setIsDragging(false);
    
    // 清除拖动计时器
    if (dragTimer) {
      clearTimeout(dragTimer);
      setDragTimer(null);
    }
    
    // 3秒后隐藏消息和重置图标状态
    if (showDragMessage) {
      setTimeout(() => {
        setShowDragMessage(false);
        setIsShowingDragMessage(false);
      }, 3000);
    }
  }, [dragTimer, showDragMessage]);

  const handleClick = (e: React.MouseEvent) => {
    if (isDragging) return;
    onIconClick?.();
  };

  // 添加全局鼠标事件监听
  useEffect(() => {
    if (isDragging) {
      document.addEventListener('mousemove', handleMouseMove);
      document.addEventListener('mouseup', handleMouseUp);
      
      return () => {
        document.removeEventListener('mousemove', handleMouseMove);
        document.removeEventListener('mouseup', handleMouseUp);
      };
    }
  }, [isDragging, dragStart, handleMouseMove, handleMouseUp]);

  // 减少调试日志，避免频繁输出
  if (!isEnabled) {
    return null;
  }

  return (
    <>
      <div
        ref={iconRef}
        className={`draggable-icon ${(isShowingNotification || isShowingDragMessage) ? 'showing-notification' : ''}`}
        style={{
          position: 'fixed',
          left: `${position.x}px`,
          top: `${position.y}px`,
          zIndex: 1001,
          cursor: isDragging ? 'grabbing' : 'grab',
        }}
        onMouseDown={handleMouseDown}
        onClick={handleClick}
      >
        <div className="icon-image-container">
          <img
            src={`${process.env.PUBLIC_URL || ''}/others/mi.png`}
            alt="Virtual Character"
            className={`icon-image ${(isShowingNotification || isShowingDragMessage) ? 'fade-out' : 'fade-in'}`}
            onError={(e) => {
              console.error('虚拟人物图片加载失败:', e.currentTarget.src);
              // 如果图片加载失败，隐藏图片元素
              e.currentTarget.style.display = 'none';
            }}
          />
          <img
            src={`${process.env.PUBLIC_URL || ''}/others/mi1.png`}
            alt="Virtual Character"
            className={`icon-image icon-image-overlay ${(isShowingNotification || isShowingDragMessage) ? 'fade-in' : 'fade-out'}`}
            onError={(e) => {
              console.error('虚拟人物图片加载失败:', e.currentTarget.src);
              // 如果图片加载失败，隐藏图片元素
              e.currentTarget.style.display = 'none';
            }}
          />
        </div>
      </div>

      {currentNotification && (
        <NotificationWindow
          notification={currentNotification}
          visible={showNotification}
          position={notificationPosition}
          iconPosition={position}
          onClose={hideNotificationWindow}
        />
      )}

      {/* 拖动5秒后显示的消息窗口 */}
      <DragMessageWindow
        visible={showDragMessage}
        position={dragMessagePosition}
        iconPosition={position}
        onClose={() => setShowDragMessage(false)}
      />
    </>
  );
};

export default DraggableIcon;